package com.ebo.synframework.synroom.executor.pool;

import com.ebo.synframework.synroom.config.PoolConfig;
import com.ebo.synframework.synroom.executor.TakeTurnsPoolSelector;
import com.ebo.synframework.synroom.executor.ThreadPoolSelector;

public class GlobalThreadPool implements LogicThreadPool {
    private final GlobalThreadPool0[] pools;

    private final ThreadPoolSelector selector;

    private final int poolNum;

    public GlobalThreadPool(int poolNum, int minThreadNum, int maxThreadNum, int queueTaskNum, String name,
            ThreadPoolSelector poolSelector) {
        this.poolNum = poolNum;
        this.pools = new GlobalThreadPool0[poolNum];
        for (int i = 0; i < poolNum; i++) {
            this.pools[i] = new GlobalThreadPool0(minThreadNum, maxThreadNum, queueTaskNum, name + "-" + i + "-");
        }
        poolSelector.setPoolsState(pools);
        this.selector = poolSelector;
    }

    public GlobalThreadPool(int poolNum, int minThreadNum, int maxThreadNum, int queueTaskNum, String name) {
        this(poolNum, minThreadNum, maxThreadNum, queueTaskNum, name, new TakeTurnsPoolSelector());
    }

    public GlobalThreadPool(PoolConfig poolConfig) {
        this(poolConfig.getPoolNum(), poolConfig.getMinThreadNum(), poolConfig.getMaxThreadNum(), poolConfig
                .getQueueTaskNum(), poolConfig.getName());
    }

    public PoolState[] getPoolsState() {
        PoolState[] states = new PoolState[pools.length];
        for (int i = 0; i < pools.length; i++) {
            states[i] = new PoolStateWrap(pools[i]);
        }
        return states;
    }

    @Override
    public void execute(Runnable runnable) {
        if (poolNum == 1) {
            pools[0].execute(runnable);
        } else {
            int index = this.selector.selectPool();
            pools[index].execute(runnable);
        }
    }

}
